package store.lunangangster.engine.impl.entity.mgr;

import java.util.List;
import store.lunangangster.bpmn.model.Task;
import store.lunangangster.engine.ProcessEngineConfiguration;
import store.lunangangster.engine.impl.entity.ExecutionEntity;
import store.lunangangster.engine.impl.entity.IdentityLinkEntity;
import store.lunangangster.engine.impl.entity.TaskEntity;
import store.lunangangster.engine.impl.entity.TaskEntityImpl;
import store.lunangangster.engine.impl.repository.EntityMatcher;

public class TaskEntityManagerImpl extends AbstractEntityManagerImpl<TaskEntity> implements TaskEntityManager {

  public TaskEntityManagerImpl(
      ProcessEngineConfiguration processEngineConfiguration) {
    super(processEngineConfiguration);
  }

  protected EntityMatcher<TaskEntity> taskWithExecutionIdMatcher = (executionId, taskEntity) -> {
    return taskEntity.getExecutionId() != null && taskEntity.getExecutionId().equals(executionId);
  };

  @Override
  public Class<? extends TaskEntity> getManagedEntityClass() {
    return TaskEntityImpl.class;
  }

  @Override
  public TaskEntity create() {
    return new TaskEntityImpl();
  }

  @Override
  public TaskEntity createTaskByExecutionAndUserTask(ExecutionEntity execution, Task task) {
    TaskEntity taskEntity = create();

    taskEntity.setExecutionId(execution.getId());
    taskEntity.setProcessInstanceId(execution.getProcessInstanceId());
    taskEntity.setProcessDefinitionId(execution.getProcessDefinitionId());

    taskEntity.setKey(task.getId()); // TaskEntity's key <==> Task's id
    taskEntity.setName(task.getName());
    taskEntity.setDescription(task.getDocumentation());
    return taskEntity;
  }

  @Override
  public void deleteTask(String taskId) {
    delete(taskId);

    IdentityLinkEntityManager identityLinkEntityManager = getIdentityLinkEntityManager();
    List<IdentityLinkEntity> identityLinkEntities = identityLinkEntityManager.selectIdentityLinkByTaskId(
        taskId);
    for (IdentityLinkEntity identityLink : identityLinkEntities) {
      identityLinkEntityManager.delete(identityLink);
    }
  }

  @Override
  @SuppressWarnings("uncheck")
  public List<TaskEntity> selectTaskByExecutionId(String executionId) {
    return selectList("selectTaskByExecutionId", executionId, taskWithExecutionIdMatcher);
  }
}
